package com.hzhq.contract.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.hzhq.contract.bean.dto.CompanyDTO;
import com.hzhq.contract.bean.dto.ContractTemplateDTO;
import com.hzhq.contract.bean.entity.*;
import com.hzhq.contract.bean.vo.ContractTemplateVO;
import com.hzhq.contract.convert.CompanyConvertBasic;
import com.hzhq.contract.convert.ContractTemplateConvertBasic;
import com.hzhq.contract.repo.ContractTypeRepository;
import com.hzhq.contract.repo.DepartRepository;
import com.hzhq.contract.repo.ContractTemplateRepository;
import com.hzhq.contract.repo.UserRepository;
import com.hzhq.contract.result.Result;
import com.hzhq.contract.service.TemplateService;
import com.hzhq.contract.status.DefaultValue;
import com.hzhq.contract.util.Page2ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * @author hzhq
 * @create 2021/4/9 12:02 上午
 * @email hzhq1255@163.com
 */
@Service
@Slf4j
public class TemplateServiceImpl implements TemplateService {

    @Autowired
    ContractTemplateRepository templateRepo;

    @Autowired
    UserRepository userRepository;

    @Autowired
    DepartRepository departRepository;

    @Autowired
    ContractTypeRepository typeRepository;

    @Autowired
    MongoTemplate mongoTemplate;


    private User getUserByName(String name){
        Optional<User> userOptional = userRepository.findByUsernameAndDeleted(name,DefaultValue.NOT_DELETED);
        return userOptional.orElse(null);
    }

    private ContractType getContractTypeByName(String name){
        Optional<ContractType> typeOptional = typeRepository.findByTypeNameAndDeleted(name,DefaultValue.NOT_DELETED);
        return typeOptional.orElse(null);
    }

    private Depart getDepartByName(String name){
        Optional<Depart> departOptional = departRepository.findByDepartNameAndDeleted(name,DefaultValue.NOT_DELETED);
        return departOptional.orElse(null);
    }


    @Override
    public Result<Object> getPageByApplicant(String username, Integer currentPage, Integer pageSize) {

        Pageable pageable = Page2ResultUtil.buildPageableByParam(
                currentPage, pageSize, Sort.by(Sort.Direction.DESC,"createTime"));

        Optional<User> userOptional = userRepository.findByUsernameAndDeleted(username, DefaultValue.NOT_DELETED);
        Page<ContractTemplate> templatePage = templateRepo.findAllByCreateUserAndDeleted(userOptional.orElse(null),DefaultValue.NOT_DELETED,pageable);

        Page<ContractTemplateVO> templateVOPage = templatePage.map(ContractTemplateConvertBasic.INSTANCE::poToDto).map(ContractTemplateConvertBasic.INSTANCE::dtoToVo);

        return Result.success(Page2ResultUtil.getPageData(templateVOPage));
    }

    @Override
    public Result<Object> getPageByDepart(String departName, Integer currentPage, Integer pageSize) {
        Pageable pageable = Page2ResultUtil.buildPageableByParam(
                currentPage,pageSize,Sort.by(Sort.Direction.DESC,"createTime"));
        Optional<Depart> depart = departRepository.findByDepartNameAndDeleted(departName,DefaultValue.NOT_DELETED);
        if (depart.isPresent()){
            Page<ContractTemplate> templatePage = templateRepo.findByDepartAndDeleted(depart.get(),DefaultValue.NOT_DELETED,pageable);
            Page<ContractTemplateVO> templateVOPage = templatePage.map(ContractTemplateConvertBasic.INSTANCE::poToDto).map(ContractTemplateConvertBasic.INSTANCE::dtoToVo);
            return Result.success(Page2ResultUtil.getPageData(templateVOPage));
        }
        return Result.error("没有这个部门");
    }



    @Override
    public Result<Object> getByTemplateName(String templateName) {
        List<ContractTemplate> templateList = templateRepo.findByTemplateNameAndDeleted(templateName,DefaultValue.NOT_DELETED);
        List<ContractTemplateDTO> templateDTOList = templateList.stream().map(ContractTemplateConvertBasic.INSTANCE::poToDto).collect(Collectors.toList());
        List<ContractTemplateVO> contractTemplateVOList = templateDTOList.stream().map(ContractTemplateConvertBasic.INSTANCE::dtoToVo).collect(Collectors.toList());
        return Result.success(contractTemplateVOList);
    }

    @Override
    public Result<Object> getOneByTemplateId(String templateId) {
        ObjectId id = new ObjectId(templateId);
        Optional<ContractTemplate> template = templateRepo.findByTemplateIdAndDeleted(id,DefaultValue.NOT_DELETED);
        if (template.isPresent()){
            ContractTemplateVO contractTemplateVO = ContractTemplateConvertBasic.INSTANCE.dtoToVo(template.map(ContractTemplateConvertBasic.INSTANCE::poToDto).orElse(null));
            return Result.success(contractTemplateVO);
        }
        return Result.error("该模板不存在");
    }

    @Override
    public Page<ContractTemplateDTO> searchAllPages(ContractTemplateDTO templateDTO, Integer currentPage, Integer pageSize) {
        ContractTemplate template = ContractTemplateConvertBasic.INSTANCE.dtoToPo(templateDTO);
        template.setDeleted(DefaultValue.NOT_DELETED);
        Pageable pageable = Page2ResultUtil.buildPageableByParam(currentPage, pageSize,
                Sort.by(Sort.Direction.DESC,"templateId"));
        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withMatcher("templateName",ExampleMatcher.GenericPropertyMatchers.contains());
        Example<ContractTemplate> templateExample = Example.of(template,exampleMatcher);
        return templateRepo.findAll(templateExample,pageable).map(ContractTemplateConvertBasic.INSTANCE::poToDto);
    }

    @Override
    public Result<Object> searchAllPageByQuery(Query query, Integer currentPage, Integer pageSize) {
        Pageable pageable = Page2ResultUtil.buildPageableByParam(currentPage, pageSize, Sort.by(Sort.Direction.DESC, ContractTemplate.TEMPLATE_ID_FIELD));
        long count = mongoTemplate.count(query, ContractTemplate.class);
        List<ContractTemplate> templates = mongoTemplate.find(query.with(pageable), ContractTemplate.class);
        List<ContractTemplateDTO> templateDTOS = templates.stream().map(ContractTemplateConvertBasic.INSTANCE::poToDto).collect(Collectors.toList());
        return Result.successWithData(Page2ResultUtil.getPageData(
                        new PageImpl<>(templateDTOS,pageable,count).map(ContractTemplateConvertBasic.INSTANCE::dtoToVo)));
    }

    @Override
    public Result<Object> saveTemplate(ContractTemplateDTO contractTemplateDTO) {


        ObjectId templateId = contractTemplateDTO.getTemplateId();
        List<ContractTemplate> contractTemplates = templateRepo.findByTemplateNameAndDeleted(contractTemplateDTO.getTemplateName(),DefaultValue.NOT_DELETED);
        ContractTemplate currentTemplate = null;
        if (contractTemplates.size() == 1){
            currentTemplate = contractTemplates.get(0);
        }
        if (templateId == null){
            if (currentTemplate != null){
                return Result.errorWithMsg("该模板已经存在");
            }
            contractTemplateDTO.setDeleted(DefaultValue.NOT_DELETED);
            contractTemplateDTO.setPassed(DefaultValue.NOT_PASSED);
            contractTemplateDTO.setCreateTime(new Date());
            ContractTemplate contractTemplate = ContractTemplateConvertBasic.INSTANCE.dtoToPo(contractTemplateDTO);
            return Result.successWithMsgAndData("保存成功",templateRepo.save(contractTemplate).getTemplateId());
        }else {
            if (currentTemplate == null){
                return Result.errorWithMsg("该模板不存在");
            }
            ContractTemplate contractTemplate = ContractTemplateConvertBasic.INSTANCE.dtoToPo(contractTemplateDTO);
            BeanUtil.copyProperties(contractTemplate,currentTemplate,new CopyOptions().ignoreNullValue());
            return Result.successWithMsgAndData("编辑成功",templateRepo.save(currentTemplate).getTemplateId());
        }
    }

    @Override
    public Result<Object> deleteTemplate(String templateId) {
        Optional<ContractTemplate> templateOptional = templateRepo.findByTemplateIdAndDeleted(new ObjectId(templateId),DefaultValue.NOT_DELETED);
        if (templateOptional.isPresent()){
            ContractTemplate template = templateOptional.get();
            template.setDeleted(DefaultValue.DELETED);
            templateRepo.save(template);
            return Result.success("删除成功");
        }
        return Result.error("没有该模板，删除失败");
    }


    @Override
    public Result<Object> getPage(Integer currentPage, Integer pageSize) {
        Pageable pageable = Page2ResultUtil.buildPageableByParam(
                currentPage,pageSize,Sort.by(Sort.Direction.DESC,"createTime"));
        Page<ContractTemplate> templatePage = templateRepo.findAllByDeleted(DefaultValue.NOT_DELETED,pageable);
        Page<ContractTemplateDTO> templateDTOPage = templatePage.map(ContractTemplateConvertBasic.INSTANCE::poToDto);
        Page<ContractTemplateVO> templateVOPage = templateDTOPage.map(ContractTemplateConvertBasic.INSTANCE::dtoToVo);
        return Result.success(Page2ResultUtil.getPageData(templateVOPage));
    }

    @Override
    public Result<Object> getList() {
        List<ContractTemplate> templateList = templateRepo.findAllByDeleted(DefaultValue.NOT_DELETED);
        List<ContractTemplateDTO> templateDTOList = templateList.stream().map(ContractTemplateConvertBasic.INSTANCE::poToDto).collect(Collectors.toList());
        return Result.success(templateDTOList.stream().map(ContractTemplateConvertBasic.INSTANCE::dtoToVo).collect(Collectors.toList()));
    }
}
